package lumis.portal;

import lumis.portal.device.Device;
import lumis.portal.device.IDevice;
import lumis.portal.serviceinterface.IServiceInterfaceRequest;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.el.ELException;
import javax.servlet.jsp.el.VariableResolver;

/**
 * <p>
 * Stores all request context on Lumis Portal.
 * </p>
 * <p>
 * The request context can be Devices informations, Session informations,
 * information from External Entities, etc.
 * </p>
 * <p>
 * It's possible to plug custom Request Context developed by user. In this case
 * just use the {@link #setEntry(String, IPortalRequestContextEntry)}.
 * </p>
 * 
 * @see {@link #IPortalRequestContext}
 * @version $Revision: 13093 $ $Date: 2011-05-28 18:40:18 -0300 (Sat, 28 May 2011) $
 * @since 6.0.0
 */
public class PortalRequestContext implements VariableResolver
{
	static final String ATTRIBUTE_PORTAL_REQUEST_CONTEXT = "lumis.portal.PortalRequestContext";

	/**
	 * The Context Map.
	 * 
	 * @since 6.0.0
	 */
	private Map<String, IPortalRequestContextEntry> contextEntriesMap = new HashMap<String, IPortalRequestContextEntry>();

	/**
	 * Returns the specific request context based on Key parameter.
	 * 
	 * @param key id of the Request context to be find. This information is
	 *          the entry key of the map.
	 *          
	 * @return the Request Context that match with key parameter.
	 * @since 6.0.0
	 */
	public Object getEntry(String key)
	{

		return getEntriesMap().get(key);
	}

	/**
	 * Returns the Device Request Context thats contains all information about
	 * the device that is making the current request.
	 * 
	 * @return the DeviceRequestContext.
	 * @since 6.0.0
	 */
	public IDevice getDeviceEntry()
	{
		return (IDevice) getEntry(Device.DEVICE_ENTRY_KEY);
	}

	/**
	 * Puts a custom request context on the context map to be used in
	 * another time.
	 * 
	 * @param key name of the Request Context. This information is the entry
	 *          key of the map.
	 * @param value the custom context.
	 * @since 6.0.0
	 */
	public void setEntry(String key, IPortalRequestContextEntry value)
	{
		getEntriesMap().put(key, value);
	}

	/**
	 * Clean up the ThreadLocal Map.
	 * 
	 * @since 6.0.0
	 */
	void clear()
	{
		getEntriesMap().clear();
	}
	
	/**
	 * Returns the Context Map.
	 * 
	 * @return the Context Map.
	 * @since 6.0.0
	 */
	private Map<String, IPortalRequestContextEntry> getEntriesMap()
	{
		return contextEntriesMap;
	}

	@SuppressWarnings("unchecked")
	public Object resolveVariable(String pName) throws ELException
	{
		return new PortalRequestContextResolverMap(contextEntriesMap.get(pName));
	}
	
	/**
	 * Returns the Portal Request Context from a given request.
	 * @param request request that contains the PortalRequestContext.
	 * @return the Portal Request Context.
	 * @since 6.0.0
	 */
	public static PortalRequestContext getPortalRequestContext(HttpServletRequest request)
	{
		return (PortalRequestContext) request.getAttribute(ATTRIBUTE_PORTAL_REQUEST_CONTEXT);
	}

	/**
	 * Returns the Portal Request Context from a given request.
	 * 
	 * @param request
	 *            request that contains the PortalRequestContext.
	 * @return the Portal Request Context.
	 * @since 6.0.0
	 */
	public static PortalRequestContext getPortalRequestContext(IServiceInterfaceRequest request)
	{
		return (PortalRequestContext) request.getAttribute(ATTRIBUTE_PORTAL_REQUEST_CONTEXT);
	}
}
